<?php declare(strict_types=1);

namespace App\Core\ModelExtend;


use App\Service\StorageService;
use Hyperf\Utils\ApplicationContext;

/**
 * 文件字段自动保存逻辑
 */
trait FileColumn
{
    /**
     * 保存文件
     * @param Model $model
     * @return bool
     */
    protected static function saveFile(object $model): bool
    {
        $query = false;
        $table = static::TABLE;
        $editorColumns = static::getEditorColumns();
        $fileNames = static::getFileColumns();
        $changeFiles = [];
        $filesUrl = trim(config('storage_base_url'), '/') . '/';

        foreach ($fileNames as $column) {
            if (empty($model->{$column})) {
                continue;
            }

            $tS = $model->{$column};
            if (!is_array($tS)) {
                $tA = [$tS];
            } else {
                $tA = $tS;
            }

            $path = $table . '/' . $model->id . '/' . $column . '/';
            $_file = [];
            foreach ($tA as $item) {
                $__files = [];
                if (is_array($item)) {
                    $__files = Arr::pluck(Arr::pluck(), 'path');
                    $__files = array_unique(array_merge(Arr::pluck(Arr::pluck(), 'file'), $__files));
                } else {
                    $__files = [$item];
                }

                foreach ($__files as $__file) {
                    $__file = str_replace($filesUrl, '', $__file);
                    if (strpos(trim($__file, '/'), 'temp/') !== 0) {
                        continue;
                    }

                    $filename = basename($__file);
                    $_file[$__file] = $path . $filename;
                }
            }

            if ($_file) {
                $changeFiles[$column] = $_file;
            }
        }

        /*
         * 移动编辑器中的文件
         */
        foreach ($editorColumns as $column) {
            if ( ! $model->{$column}) {
                continue;
            }

	        $imgs = [];
	        $path = $table . '/' . $model->id . '/' . $column;
	        $imgpreg = "/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i";
	        preg_match_all($imgpreg, $model->{$column}, $imgs);

	        if (!$imgs || empty($imgs[1])) continue;

	        $files = [];
	        foreach ($imgs[1] as $item) {
		        $files[] = $item;
	        }

            $files = array_unique($files);
            $temp = [];
            foreach ($files as $k => $item) {
                $_path = trim($path, '/') . '/' . $k . '/';
                $file = str_replace($filesUrl, '', $item);
                if (strpos($item, $filesUrl) !== 0) {
                    continue;
                }
                //检查是否存入的是临时文件夹
                if (strpos($file, 'temp/') !== 0) {
                    continue;
                }

                $filename = basename($file);
                $temp[$file] = $_path . $filename;
            }


	        if ($temp) {
		        $changeFiles[$column] = $temp;
	        }

            if (strpos($model->{$column}, $filesUrl) !== false) {
                $model->{$column} = str_replace($filesUrl, '{storage_base_url}', $model->{$column});
                $query = true;
            }
        }

        //保存替换文件
        if ($query) {
            $model->save();
        }

        //异步更改文件路径
        if ($changeFiles) {
            try {
                $storageService = ApplicationContext::getContainer()->get(StorageService::class);
                $storageService->asynCopy(static::class, $model->id, $changeFiles);
            } catch (\Exception $e) {
                responseError('文件保存失败');
            }
        }

        return true;
    }

    /**
     * 获取所有文件字段
     * @return array
     */
    public static function getFileColumns(): array
    {
        $columns = [];
        foreach (static::COLUMN as $column => $item) {
            if (!isset($item['is_file']) || !$item['is_file']) {
                continue;
            }

            $columns[] = $column;
        }

        return $columns;
    }

    /**
     * 获取编辑器字段
     * @return array
     */
    public static function getEditorColumns(): array
    {
        $columns = [];
        foreach (static::COLUMN as $column => $item) {
            if (!isset($item['is_editor']) || !$item['is_editor']) {
                continue;
            }

            $columns[] = $column;
        }

        return $columns;
    }
}
